﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Resources;

namespace hse_2013_local_game2d
{
    public partial class MainForm : Form
    {
        int pointsCounter = 0;
        bool gamePaused = false;
        bool gameIsOn = false;
        bool gameResult = false;
        bool SUCCESS = false;
        //ResXResourceSet res = new ResXResourceSet("../../Properties/Resources.resx");
        public delegate void GameEventHandler();
        public static event GameEventHandler GameStart;
        public static event GameEventHandler GameEnd;
        Lavel currentLavel;
        Random rd=new Random();
        bool up = false;
        bool down = false;
        Config data = new Config("../../Config.txt");
        Ship[] ships;
        Bomb currentBomb;
        int smoothCounter = 0;
        double smoothValue = 0;
        int moveChordsCounter = 0;
        Plane plane;
        Wave frontWave;
        Wave backWave;
        public MainForm()
        {
            InitializeComponent();
        }
        void menu1_CloseGame(object sender, EventArgs e)
        {
            this.Close();
        }
        void menu1_StartGame(object sender, EventArgs e)
        {
            GameStart();
            this.Focus();
        }

        void Ship_ShipHit(Ship s)
        {
            pointsCounter += 100;
        }
        void MainForm_GameEnd()
        {
            currentLavel = null;
            this.BackColor = Color.WhiteSmoke;
            plane = null;
            frontWave = null;
            backWave = null;
            ships = null;
            points.Visible = false;
            time.Enabled = false;
            gameIsOn = false;
            moveChordsCounter = 0;
            pointsCounter = 0;
            smoothCounter = 0;
            smoothValue = 0;
            up = false;
            down = false;
            lbl_Failed.Visible = false;
            lbl_success.Visible = false;
            this.Invalidate();
        }
        void MainForm_GameStart()
        {
            currentLavel = Lavels.Lavel1;
            this.BackColor = currentLavel.BackgroundColor;
            //plane = new Plane(new Point(0, 150), 9, 0, (Image)res.GetObject("_1"), (Image)res.GetObject("_1_on_fire"), (Image)res.GetObject("splash"));
            plane = new Plane(new Point(0, 150), 9, 0, new Bitmap("../../Resources/1.png"), new Bitmap("../../Resources/1_on_fire.png"), new Bitmap("../../Resources/splash.png"));
            frontWave = new Wave(240, -0.3, plane, currentLavel.FrontWaveColor);
            backWave = new Wave(235, 0.1, plane, currentLavel.BackWaveColor);
            ships = SetShips(currentLavel.ShipChords);
            points.Visible = true;
            time.Enabled = true;
            gameIsOn = true;
        }
        void Plane_PlaneBurn(Plane p)
        {
            p.BurnModeOn();
        }
        void Bomb_Explosion(Bomb B)
        {
            B.BurnMode = true;
        }
        private void PauseGame()
        {
            if (!gameResult)
            {
                if (!gamePaused)
                {
                    gamePaused = true;
                    time.Enabled = false;
                    restartButton.Visible = true;
                    continueButton.Visible = true;
                    menuButton.Visible = true;
                    this.Invalidate();
                }
                else
                {
                    restartButton.Visible = false;
                    continueButton.Visible = false;
                    menuButton.Visible = false;
                    gamePaused = false;
                    time.Enabled = true;
                    moveChordsCounter--;
                }
            }

        }
        private void ResultGame(bool thePlaneSunk)
        {
            gameResult=true;
            if (thePlaneSunk)
            {
                lbl_Failed.Visible = true;
                time.Enabled = false;
                restartButton.Visible = true;
                menuButton.Visible = true;
                SUCCESS=false;
                this.Invalidate();
            }
            else
            {
                if (pointsCounter >= currentLavel.PointsToReach)
                {
                    lbl_success.Visible = true;
                    time.Enabled = false;
                    restartButton.Visible = true;
                    menuButton.Visible = true;
                    SUCCESS = true;
                    this.Invalidate();
                }
                else
                {
                    ResultGame(true);
                }
            }

        }
        private Ship[] SetShips(int[] shipChords)
        {
            List<Ship> ships= new List<Ship>();
            foreach (int chord in shipChords)
            {
                ships.Add(new Ship(backWave, chord, 40, currentLavel.ShipView, currentLavel.AfterExplosionShipView,rd.Next(0,3)));
            }
            return ships.ToArray();
        }
        private void Plane_MoveChords(Graphics g)
        {
            if (!gamePaused)
            {
                moveChordsCounter++;
            }
                g.TranslateTransform(-plane.Velocity * moveChordsCounter, 0);
            
        }
        private void time_Tick(object sender, EventArgs e)
        {
            points.Text = pointsCounter.ToString()+"/"+currentLavel.PointsToReach.ToString();
            if (up&plane.FlightMode)
            {
                SmoothChange(-1);
            }
            if (down&plane.FlightMode)
            {
                SmoothChange(0.5);
            }
            if (smoothCounter != 0)
            {
                smoothCounter--;
                plane.UVelocity = plane.UVelocity + smoothValue;
            }
            if (plane.Position.X > 250&!plane.FlightMode&!plane.BurnMode)
            {
                SmoothChange(-3);
                plane.FlightModeOn();                
            }
            if (plane.Position.X > currentLavel.LevelLength)
            {
                ResultGame(false);
            }
            if (plane.Position.Y > 175&!plane.DrawnMode)
            {
                plane.DrawnModeOn();
                ResultGame(true);
            }
            plane.Move();
            backWave.Move();
            frontWave.Move();
            foreach (Ship ship in ships)
            {
                ship.Move();
                ship.PlaneHit(plane);
            }
            if (currentBomb!=null)
            {               
                currentBomb.Move();
                foreach (Ship ship in ships)
                {
                    ship.BombHit(currentBomb);
                }
                if ((currentBomb.Position.Y > 220)|(currentBomb.ExplosionFrameCounter==10))
                {
                    currentBomb = null;
                }
            }
            this.Invalidate();
        }
        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            if (gameIsOn)
            {
                plane.OnPaint(e.Graphics);
                backWave.OnPaint(e.Graphics);
                e.Graphics.FillRectangle(new HatchBrush(HatchStyle.LargeCheckerBoard, Color.Black, Color.White), currentLavel.LevelLength, 0, 20, 400);
                foreach (Ship ship in ships)
                {
                    ship.OnPaint(e.Graphics);
                }
                frontWave.OnPaint(e.Graphics);
                if (currentBomb != null)
                { currentBomb.OnPaint(e.Graphics); }
                e.Graphics.DrawLine(Pens.Red, 0, 200, 1000, 200);
                e.Graphics.DrawLine(Pens.PowderBlue, 250, 0, 250, 1000);
                if (gamePaused)
                {
                    if (!plane.RideMode)
                    {
                        e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(128, 0, 0, 0)), plane.Position.X - 300, 0, 1000, 500);
                    }
                    else
                    {
                        e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(128, 0, 0, 0)), 0, 0, 1000, 500);
                    }
                }
                if (gameResult)
                {
                    e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(128, 0, 0, 0)), plane.Position.X - 300, 0, 1000, 500);
                }
            }
        }
        private void SmoothChange(double value)
        {
            smoothCounter = 3;
            smoothValue = value / 3;
        }
        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (gameIsOn)
            {
                if (e.KeyCode == Keys.Up)
                {
                    up = true;
                }
                if (e.KeyCode == Keys.Down)
                {
                    down = true;
                }
                if (e.KeyCode == Keys.Space)
                {
                    if (data.BombType == 0 & currentBomb == null)
                    { currentBomb = new WaterBomb(new Point(plane.Position.X + 50, plane.Position.Y + 50), new Bitmap("../../Resources/bomb_explosion.png"), new Bitmap("../../Resources/bomb.png"), plane.Angle, plane.Velocity, plane.UVelocity); }
                    if (data.BombType == 1 & currentBomb == null)
                    { currentBomb = new Missile(new Point(plane.Position.X + 50, plane.Position.Y + 50), new Bitmap("../../Resources/rocket_explosion.png"), new Bitmap("../../Resources/rocket.png"), plane.Angle, plane.Velocity); }
                    if (data.BombType == 2 & currentBomb == null)
                    { }
                }
                if (e.KeyCode == Keys.P)
                {
                    PauseGame();
                }
                if (e.KeyCode == Keys.D1)
                {
                    data.BombType = 0;
                }
                if (e.KeyCode == Keys.D2)
                {
                    data.BombType = 1;
                }
            }
        }
        private void MainForm_KeyUp(object sender, KeyEventArgs e)
        {
            if (gameIsOn)
            {
                if (e.KeyCode == Keys.Up)
                {
                    up = false;
                }
                if (e.KeyCode == Keys.Down)
                {
                    down = false;
                }
            }
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            menu1.CloseGame += new EventHandler(menu1_CloseGame);
            menu1.StartGame += new EventHandler(menu1_StartGame);
            Ship.ShipHit += new Ship.ShipEvents(Ship_ShipHit);
            Plane.MoveChords += new Plane.TransformNeeded(Plane_MoveChords);
            Bomb.Explosion += new Bomb.BombExploaded(Bomb_Explosion);
            Plane.PlaneBurn += new Plane.PlaneExploaded(Plane_PlaneBurn);
            GameStart += new GameEventHandler(MainForm_GameStart);
            GameEnd += new GameEventHandler(MainForm_GameEnd);
        }
        private void MainForm_Click(object sender, EventArgs e)
        {
        }
        private void restartButton_Click(object sender, EventArgs e)
        {
            gameResult = false;
            restartButton.Visible = false;
            menuButton.Visible = false;
            if (gamePaused)
            {
                PauseGame();
            }
            GameEnd();
            GameStart();
            this.Focus();
        }
        private void continueButton_Click(object sender, EventArgs e)
        {
            PauseGame();
            this.Focus();
        }

        private void menuButton_Click(object sender, EventArgs e)
        {
            gameResult = false;
            restartButton.Visible = false;
            menuButton.Visible = false;
            if (gamePaused)
            {
                PauseGame();
            }
            GameEnd();
            menu1.Visible = true;
        }
    }
}
